<script setup lang="ts">
import { Plus ,Delete} from '@element-plus/icons-vue'
import { onMounted,watch,ref } from 'vue'
import { getTrademarkListAPI,getSpuDetailAPI, getScaleAttrListAPI,updateSpuAPI,addSpuAPI } from '@/api/product/spu'
import type { BrandItem } from '@/types/product/brand'
import type { SPUItem, SPUImageItem,ResponseSaleAttrListDataItem,SPUSaleAttrItem,SPUSaleAttListItem} from '@/types/product/spu'
import { ElMessage, FormInstance} from 'element-plus'



// 商品属性基础数据
const ScaleData = ref<ResponseSaleAttrListDataItem[]>([])

// 父组件触发事件
const emit = defineEmits(['cancel'])

// 接收父组件参数、
const props = defineProps<{
    spuId: string | number,
    categoryId: string | number
}>()

// 点击取消
const handelCancel =  () => {

    // 清空数据
    formData.value = {
        id: '',
        spuName: '',
        tmId: '',
        description: '',
        spuImageList: [],
        spuSaleAttrList: [],
        category3Id: ''
    }
    // 清空所有校验记录
    formRef.value?.resetFields()
    emit('cancel')
}

// 监听spuId变化
watch(() => props.spuId, async (newVal) => {
    if(newVal) {
        await getSpuDetail(newVal)   
    }
})

// 品牌数据
const brandList = ref<BrandItem[]>([])

// 获取品牌数据
const getBrandList = async () => {
    const res = await getTrademarkListAPI()
    console.log(res.data);
    
    brandList.value = res.data
}

// 表单数据
const formData = ref<SPUItem>({
    id: '',
    spuName: '',
    tmId: '',
    description: '',
    spuImageList: [],
    spuSaleAttrList: [],
    category3Id:  props.categoryId,
    
})

// 获取spu详情数据
const getSpuDetail = async (spuId: string | number) => {
    loading.value = true
    const res = await getSpuDetailAPI(spuId)
    console.log(res.data);
    res.data.description = res.data.description.replace(/\n/g, ":")
    res.data.spuImageList = res.data.spuImageList.map((item : SPUImageItem) => {
        return {
            name: item.imgName,
            url: item.imgUrl,
            spuId: item.spuId,
            id: item.id
        }
    })
    formData.value = res.data
    const hascale = res.data.spuSaleAttrList.map((item:SPUSaleAttrItem) => item.saleAttrName)
 
        saleAttrList.value = ScaleData.value.filter(item => {
        if(hascale.includes(item.name)) {
            return false
        } else {
            return true
        }
    }) 
    
    
    loading.value = false
}

// 销售属性列表
const saleAttrList = ref<ResponseSaleAttrListDataItem[]>([])

// 获取所有销售属性
const getSaleAttrList = async () => {
    
    const res = await getScaleAttrListAPI()
    console.log(res.data);

    ScaleData.value = res.data
    saleAttrList.value = res.data

}

// 更新spu / 新增
const updateSpu =() => {
    // 校验表单
    formRef.value?.validate(async (valid:any) => {
        if(valid) {
                // 重新构造图片数组
            const imges = formData.value.spuImageList.map((item: SPUImageItem) => {
                    return {
                        imgName: item.name || item.imgName,
                        imgUrl: item.url || item.imgUrl,
                        id: item.id,
                        spuId: item.spuId,
                    }
                })
                // 组合请求数据
            const data  = {...formData.value, spuImageList: imges,category3Id: props.categoryId}
            // 判断是更新还是新增
            if(props.spuId) {
                // 更新
                const res = await updateSpuAPI(data)
                if(res.code === 200) {
                    // 关闭当前页面。重新转换到列表显示页面
                    ElMessage.success("更新成功")
                    handelCancel()
                }
            } else {
                // 新增
                const res = await addSpuAPI(data)
                if(res.code === 200) {
                    // 关闭当前页面。重新转换到列表显示页面
                    ElMessage.success("新增成功")
                    handelCancel()
                }
            }
        }
    })
    
}

// 页面加载效果
const loading = ref(false)

// 属性选择框数据
const attrValueSelectId = ref<string | number>('')

// 销售属性选择
const handleSelectionChange = () => {
    
    const saleItem = saleAttrList.value.find(item => item.id === attrValueSelectId.value)

    const item = {
        baseSaleAttrId: saleItem?.id,
        saleAttrName: saleItem?.name,
        spuSaleAttrValueList: [],
        spuId: props.spuId,
    }
    formData.value.spuSaleAttrList.push(item)
    const hascale = formData.value.spuSaleAttrList.map((item:SPUSaleAttrItem) => item.saleAttrName)

    saleAttrList.value = ScaleData.value.filter(item => {
        if(hascale.includes(item.name)) {
            return false
        } else {
            return true
        }
    })
    attrValueSelectId.value = ''
}

// 删除销售属性
const deleteSaleAttr = (index: number) => {
    formData.value.spuSaleAttrList.splice(index,1)
    const hascale = formData.value.spuSaleAttrList.map((item:SPUSaleAttrItem) => item.saleAttrName)

saleAttrList.value = ScaleData.value.filter(item => {
    if(hascale.includes(item.name)) {
        return false
    } else {
        return true
    }
})
}

// 图片上传成功
const handleAvatarSuccess = (res: any) => {
    formData.value.spuImageList[formData.value.spuImageList.length - 1] = {
        url: res.data,
        spuId: props.spuId,
        name: '测试图片名称'
    }
}

// 图片预览功能
const previewImage = ref('')

// 图片预览控制
const previewVisible = ref(false)

// 开启预览
const handlePreview = (file: any) => {
    previewImage.value = file.url
    previewVisible.value = true
    
}

// 图片上传格式限制
const beforeAvatarUpload = (file: any) => {
    // 判断上传文件类型
    if(file.type === 'image/png' || file.type === 'image/jpeg' || file.type === 'image/gif') {
        if(file.size / 1024 / 1024 < 10) {
            return true
        } else {
            ElMessage.error("图片大小不能超过10M")
            return false
        }
    } else {
        ElMessage.error("只允许上传png、jpeg、gif格式的图片")
        return false
    }
}

// 删除属性值
const deleteAttrValue = (row: SPUSaleAttrItem, index: number) => {
    row.spuSaleAttrValueList.splice(index, 1)
}

// 添加属性值
const addAttrValue = (row: SPUSaleAttrItem) => {
    row.spuSaleAttrValueList.push({
        baseSaleAttrId: row.baseSaleAttrId,
        saleAttrName: row.saleAttrName,
        saleAttrValueName: "",
        spuId: props.spuId,
        flag: true
    })
}

// 确认添加属性值
const confirmAddAttrValue = (row: SPUSaleAttrItem, item: SPUSaleAttListItem,index: number) => {
    if(item.saleAttrValueName.trim() === '') {
        ElMessage.error("属性值不能为空")
        row.spuSaleAttrValueList.splice(index,1)
        return
    } else {
        item.flag = false
    }
}

// 输入框聚焦效果
const handle = (el: any) => {
    if(el !== null) {
        el.focus()
    }
}

// 点击标签切换为输入框
const changeInput = (item: any) => {
    item.flag =  true
}

// 数据格式校验
const rules = {
    spuName: [
        {
            required: true,
            message: '请输入spu名称',
            trigger: 'blur'
        },
        {
            min: 2,
            max: 10,
            message: "长度为2到10个字符",
            trigger: 'blur'
        }
    ],
    tmId: [
        {
            required: true,
            message: '请选择品牌'
        }
    ],
    description: [
        {
            required: true,
            message: '请输入spu描述',
            trigger: 'blur'
        },
    ],
    spuImageList: [
        {
            required: true,
            message: '请选择spu图片',
            trigger: 'change'
        }
    ],
}

// 表单对象
const formRef = ref<FormInstance>()

// 初始化
onMounted(() => { 
    getBrandList()
    getSaleAttrList()
    
    
})


</script>
<template>
    <el-card>
        <el-form ref="formRef" :model="formData" :rules="rules" v-loading="loading" label-width="100px">
            <el-form-item label="spu名称" prop="spuName">
                <el-input v-model="formData.spuName" style="width: 240px;"></el-input>
            </el-form-item>
            <el-form-item label="spu品牌" prop="tmId">
                <el-select
                    placeholder="请选择品牌"
                    style="width: 240px"
                    v-model="formData.tmId"
                    >
                    <el-option
                        v-for="item in brandList"
                        :key="item.id"
                        :label="item.tmName"
                        :value="item.id"
                    />
                </el-select>
            </el-form-item>
            <el-form-item label="spu描述" prop="description">
                <el-input v-model="formData.description" type="textarea" ></el-input>
            </el-form-item>
            <el-form-item label="spu图片" prop="spuImageList">
                <el-upload
                    action="/admin/product/fileUpload"
                    list-type="picture-card"
                    :on-preview="handlePreview"
                    :on-remove="() => {}"
                    v-model:file-list="formData.spuImageList"
                    :on-success="handleAvatarSuccess"
                    :before-upload="beforeAvatarUpload"
                    
                >
                    <el-icon><Plus /></el-icon>
                </el-upload>

                <el-dialog style="width: 600px;" v-model="previewVisible">
                    <img w-full style="width: 100%;" :src="previewImage"  alt="Preview Image" />
                </el-dialog>
            </el-form-item>
            <el-form-item label="spu销售属性">
                <el-select
                    placeholder="请选择销售属性"
                    style="width: 240px"
                    v-model="attrValueSelectId"
                    >
                    <el-option
                        v-for="item in saleAttrList"
                        :key="item.id"
                        :label="item.name"
                        :value="item.id"
                    />
                </el-select>
                <el-button :disabled="!attrValueSelectId" @click="handleSelectionChange" style="margin-left: 10px;" type="primary" :icon="Plus">添加销售属性</el-button>
            </el-form-item>
            <el-form-item>
                <el-table :data="formData.spuSaleAttrList" stripe border style="margin: 10px 0; " >
                    <el-table-column header-align="center" align="center" width="80px" label="序号"  type="index"></el-table-column>
                    <el-table-column header-align="center" align="center" width="200px" label="属性名" prop="saleAttrName"></el-table-column>
                    <el-table-column header-align="center" align="center" label="属性值">
                        <template v-slot="{ row}">
                            <span v-for="(item,index) in row.spuSaleAttrValueList" :key="index">
                            <el-tag @click="changeInput(item)" v-if="!item?.flag"  @close=" deleteAttrValue(row,index)" closable >{{ item.saleAttrValueName }}</el-tag>
                            <el-input :ref="handle" v-else autofocus placeholder="属性值" style="width: 100px;" v-model="item.saleAttrValueName" @blur="confirmAddAttrValue(row,item,index)" @keyup.enter="confirmAddAttrValue(row,item,index)"></el-input>
                            </span>
                            <el-button @click="addAttrValue(row)" style="margin-left: 10px;" type="success" size="small" :icon="Plus"></el-button>
                        </template>
                    </el-table-column>
                    <el-table-column  header-align="center" align="center" width="180px" label="操作">
                        <template v-slot="{ row,$index }">
                            <el-popconfirm title="确定要删除该属性吗?" confirm-button-text="确认" cancel-button-text="取消" @confirm="deleteSaleAttr($index)">
                                <template #reference>
                                    <el-button type="danger" :data="row" circle :icon="Delete"></el-button>
                                </template>
                            </el-popconfirm>
                            
                        </template>
                    </el-table-column>
                </el-table>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="updateSpu">保存</el-button>
                <el-button @click="handelCancel">取消</el-button>
            </el-form-item>
        </el-form>
    </el-card>
</template>



<style scoped>

::v-deep(.el-table ) {
    margin-bottom: 0;
}
</style>